#include "mainconfig.h"
#include <time.h>
#include "iconv.h"
#include "commclass.h"

#define MAIN_SECTION    "Global"

// int型
#define GETINT(section, name, value) \
    value = cfg.GetInt(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}

#define GETUSHORT(section, name, value) \
    value = (unsigned short)cfg.GetInt(section, name, &iRet); \
    if (iRet) \
    { \
        CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    }

// char数组
#define GETSTR(section, name, value) \
    s = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	} \
    iRet = ct_snprintf(CT_STRSIZE(value), "%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// CTSizeString数组
#define GETSIZESTRING(section, name, value) \
    s = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", section, name, iRet)); \
	} \
    iRet = value.Set("%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", section, name, sizeof(value))); \
    }

// string
#define GETSTRING(section, name, value) \
    value = cfg.GetString(section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}

/*-- Begin: Added by LincLiu on 2009-10-28: Define macro to get config value from dedicated file --*/
// int型
#define GETINTFROMFILE(cfgFile, section, name, value) \
    value = cfg.GetInt(cfgFile, section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}

#define GETUSHORTFROMFILE(cfgFile, section, name, value) \
    value = (unsigned short)cfg.GetInt(cfgFile, section, name, &iRet); \
    if (iRet) \
    { \
        CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
    }


// char数组
#define GETSTRFROMFILE(cfgFile, section, name, value) \
    s = cfg.GetString(cfgFile, section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	} \
    iRet = ct_snprintf(CT_STRSIZE(value), "%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// CTSizeString数组
#define GETSIZESTRINGFROMEFILE(cfgFile, section, name, value) \
    s = cfg.GetString(cfgFile, section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	} \
    iRet = value.Set("%s", s.c_str()); \
    if (iRet < 0) \
    { \
        CT_THROW(("[%s]%s too long, over %d", MAIN_SECTION, name, sizeof(value))); \
    }

// string
#define GETSTRINGFROMFILE(cfgFile, section, name, value) \
    value = cfg.GetString(cfgFile, section, name, &iRet); \
	if (iRet) \
	{ \
		CT_THROW(("[%s]%s failed %d", MAIN_SECTION, name, iRet)); \
	}


/*-- End: Added by LincLiu on 2009-10-28: Define macro to get config value from dedicated file --*/

extern int g_iLogCmdExecTimeFlag;

int CMainConfig::LoadConfig()
{
    CTConfig cfg;
    string s;
    int iRet = cfg.LoadConfig(FILE_CONFIG);
    if (iRet)
    {
        CT_THROW(("LoadConfig failed: %d", iRet));
    }

    GETSIZESTRING(MAIN_SECTION, "MgrShmKey", MgrShmKey);
    GETSIZESTRING(MAIN_SECTION, "UptShmKey", UptShmKey);
//    Ftok(MgrShmKey.GetBuffer(), MgrShmKey.GetBufferLen());

    GETSIZESTRING(MAIN_SECTION, "FrontEndShmKey", FrontEndShmKey);
//    Ftok(FrontEndShmKey.GetBuffer(), FrontEndShmKey.GetBufferLen());

    GETINT(MAIN_SECTION, "FrontEndShmSize", FrontEndShmSize);
    GETSIZESTRING(MAIN_SECTION, "FrontEndSocket", FrontEndSocket);
    GETSIZESTRING(MAIN_SECTION, "BackEndSocket", BackEndSocket);

    GETSIZESTRING(MAIN_SECTION, "SenWordCfgFile", SenWordCfgFilePath);
    GETSIZESTRING(MAIN_SECTION, "CrossDomainCfgFile", CrossDomainCfgFilePath);

    GETSIZESTRING(MAIN_SECTION, "DBHost", DBHost);
    int iDBPort = 0;
    GETINT(MAIN_SECTION, "DBPort", iDBPort);
    DBPort = (unsigned short)(iDBPort & 0xFFFF);

    GETSIZESTRING(MAIN_SECTION, "ApiHost", ApiHost);
    int iApiPort = 0;
    GETINT(MAIN_SECTION, "ApiPort", iApiPort);
    ApiPort = (unsigned short)(iApiPort & 0xFFFF);

    GETSIZESTRING(MAIN_SECTION, "AdminHost", AdminHost);
    int iAdminPort = 0;
    GETINT(MAIN_SECTION, "AdminPort", iAdminPort);
    AdminPort = (unsigned short)(iAdminPort & 0xFFFF);

    GETSIZESTRING(MAIN_SECTION, "AppID", AppID);
    GETSIZESTRING(MAIN_SECTION, "QQMallIconPath", QQMallIconPath);    

    GETSIZESTRING(MAIN_SECTION, "MemoryDBHost", MemoryDBHost);
    int iMemoryDBPort = 0;
    GETINT(MAIN_SECTION, "MemoryDBPort", iMemoryDBPort);
    MemoryDBPort = (unsigned short)(iMemoryDBPort & 0xFFFF);

    int iOpenMemoryDB = 0;
    GETINT(MAIN_SECTION, "OpenMemoryDB", iOpenMemoryDB);
    OpenMemoryDB = (unsigned short)(iOpenMemoryDB & 0xFFFF);

    GETSIZESTRING(MAIN_SECTION, "Wan32Key", Wan32Key);
    GETSIZESTRING(MAIN_SECTION, "Wan32AdminHost", Wan32AdminHost);
    GETSIZESTRING(MAIN_SECTION, "Wan32AdminHost2", Wan32AdminHost2);

    int iZoneID = 0;
    GETINT(MAIN_SECTION, "ZoneID", iZoneID);
    ZoneID = (unsigned int)iZoneID;
    if (ZoneID > MAX_ZONE_COUNT)
    {
        return RET_ERROR_ZONEID;
    }

    GETSIZESTRING("Logic", "TaskConfigFilePath", TaskConfigFilePath);
    GETSIZESTRING("Logic", "ItemConfigFilePath", ItemConfigFilePath);
    GETSIZESTRING("Logic", "EquipConfigFilePath", EquipConfigFilePath);
    GETSIZESTRING("Logic", "RoleConfigFilePath", RoleConfigFilePath);
    GETSIZESTRING("Logic", "ShopConfigFilePath", ShopConfigFilePath);
    GETSIZESTRING("Logic", "MonsterConfigFilePath", MonsterConfigFilePath);
    GETSIZESTRING("Logic", "InstanceConfigFilePath", InstanceConfigFilePath);
    GETSIZESTRING("Logic", "PartnerConfigFilePath", PartnerConfigFilePath);
    GETSIZESTRING("Logic", "SkillConfigFilePath", SkillConfigFilePath);
    GETSIZESTRING("Logic", "CardConfigFilePath", CardConfigFilePath);
    GETSIZESTRING("Logic", "SoulConfigFilePath", SoulConfigFilePath);
    GETSIZESTRING("Logic", "GardenConfigFilePath", GardenConfigFilePath);
    GETSIZESTRING("Logic", "DrugConfigFilePath", DrugConfigFilePath);
    GETSIZESTRING("Logic", "ArenaConfigFilePath", ArenaConfigFilePath);
    GETSIZESTRING("Logic", "ClanConfigFilePath", ClanConfigFilePath);
    GETSIZESTRING("Logic", "StatusConfigFilePath", StatusConfigFilePath);
    GETSIZESTRING("Logic", "ActConfigFilePath", ActConfigFilePath);
    GETSIZESTRING("Logic", "SceneConfigFilePath", SceneConfigFilePath);
    GETSIZESTRING("Logic", "LessonConfigFilePath", LessonConfigFilePath);
    GETSIZESTRING("Logic", "SpecialAccountConfigFilePath", SpecialAccountConfigFilePath);
    GETSIZESTRING("Logic", "EnergyConfigFilePath", EnergyConfigFilePath);
    GETSIZESTRING("Logic", "DailyTaskConfigFilePath", DailyTaskConfigFilePath);
    GETSIZESTRING("Logic", "TreasureConfigFilePath", TreasureConfigFilePath);
    GETSIZESTRING("Logic", "PetConfigFilePath", PetConfigFilePath);
    GETSIZESTRING("Logic", "CoolingConfigFilePath", CoolingConfigFilePath);
    GETSIZESTRING("Logic", "MuseConfigFilePath", MuseConfigFilePath);
    GETSIZESTRING("Logic", "MountConfigFilePath", MountConfigFilePath);
    GETSIZESTRING("Logic", "FashionConfigFilePath", FashionConfigFilePath);
    GETSIZESTRING("Logic", "VipConfigFilePath", VipConfigFilePath);
    GETSIZESTRING("Logic", "MagicDoorConfigFilePath", MagicDoorConfigFilePath);
    GETSIZESTRING("Logic", "AcademyConfigFilePath", AcademyConfigFilePath);
    GETSIZESTRING("Logic", "RewardConfigFilePath", RewardConfigFilePath);
    GETSIZESTRING("Logic", "SysOpenConfigFilePath", SysOpenConfigFilePath);
    GETSIZESTRING("Logic", "DiceConfigFilePath", DiceConfigFilePath);
    GETSIZESTRING("Logic", "ModParaConfigFilePath", ModParaConfigFilePath);
    GETSIZESTRING("Logic", "AuctionConfigFilePath", AuctionConfigFilePath);
    GETSIZESTRING("Logic", "FriendConfigFilePath", FriendConfigFilePath);
    GETSIZESTRING("Logic", "QQMallConfigFilePath", QQMallConfigFilePath);
    GETSIZESTRING("Logic", "PotentialConfigFilePath", PotentialConfigFilePath);
    GETSIZESTRING("Logic", "ZoneConfigFilePath", ZoneConfigFilePath);
    GETSIZESTRING("Logic", "MarketConfigFilePath", MarketConfigFilePath);

    
	iRet = LoadLogConfig();
    if (iRet == 0)
    {
        iRet = LoadDynamicConfig();
    }
    return iRet;

}

int CMainConfig::LoadDynamicConfig()
{
    string s;
    CTConfig cfg;
    int iRet = cfg.LoadConfig(FILE_CONFIG);
    if (iRet)
    {
        CT_THROW(("LoadConfig failed: %d", iRet));
        return -1;
    }

    //数据刷新相关配置
    GETINT(MAIN_SECTION, "InitDataFlushNum", InitDataFlushNum);
    GETINT(MAIN_SECTION, "MaxDataFlushNum", MaxDataFlushNum);

    return 0;
}

int CMainConfig::ReloadConfig()
{
    int iRet =  LoadLogConfig();
    if (iRet == 0)
    {
        return LoadDynamicConfig();
    }
    return iRet;
}

int CMainConfig::LoadLogConfig()
{
	CTConfig cfg;
	int iRet = cfg.LoadConfig(FILE_CONFIG);
	if (iRet)
	{
		CT_THROW(("LoadConfig failed: %d", iRet));
	}

    int iLogFileNum = 0, iLogFileSize = 0;
	GETINT(MAIN_SECTION, "LogFileNum", iLogFileNum);
	GETINT(MAIN_SECTION, "LogFileSize", iLogFileSize);
	CT_NLOG->Init(ENamed, NULL, FILE_NORMALLOG, iLogFileSize, iLogFileNum);
	CT_ELOG->Init(ENamed, NULL, FILE_ERRORLOG, iLogFileSize, iLogFileNum);
    CT_WLOG->Init(ENamed, NULL, FILE_WARLOG, iLogFileSize, iLogFileNum);
	CT_STAT->Init(ENamed, NULL, FILE_STATLOG, iLogFileSize, iLogFileNum);
    CT_UPT->Init(ENamed, NULL, FILE_UPDATE, iLogFileSize, iLogFileNum);
    CT_BAT->Init(ENamed, NULL, FILE_BATTLE, iLogFileSize, iLogFileNum);
    CT_MSG->Init(ENamed, NULL, FILE_MESSAGE, iLogFileSize, iLogFileNum);    
	CT_STAT->SetFormat(ETime|ENewLine);

    //账单
    LogFilePrefix.Set("%u_", CONF->ZoneID); //已经初始化直接用
    CT_BIL->Init(EHour, BILL_PATH, BILL_SUFFIX, iLogFileSize, iLogFileNum, LogFilePrefix.Get());   
	CT_BIL->SetFormat(ENewLine);

	// 设置filter
    string str;
	GETSTRING(MAIN_SECTION, "LogFormat", str)
	CT_NLOG->SetFormatByStr(str.c_str());
	CT_ELOG->SetFormatByStr(str.c_str());
    CT_WLOG->SetFormatByStr(str.c_str());
    CT_UPT->SetFormatByStr("time|pid|newline");
    CT_BAT->SetFormatByStr(str.c_str());
    CT_MSG->SetFormatByStr("time|pid|newline");

	// 设置filter
	GETSTRING(MAIN_SECTION, "LogFilter", str)
	CT_NLOG->SetFilterByStr(str.c_str());
	CT_ELOG->SetFilterByStr(str.c_str());
    CT_WLOG->SetFilterByStr(str.c_str());
    CT_UPT->SetFilterByStr("fatal|error|warning|info|trace");
    CT_BAT->SetFilterByStr(str.c_str());
    CT_MSG->SetFilterByStr(str.c_str());

	CT_INFO(("LogFormat=%d LogFilter=%d", CT_NLOG->GetFormat(), CT_NLOG->GetFilter()));
    return 0;
}

/**
* @brief   gbToUtf8
* function:convert gb  to utf
@param :  str: /in,out/the operating string
@retbalue:-1 failed ,0 success
*/
std::string GbToUtf8(const std::string  str)
{
    int iLen = str.length()*3/2 + 100;
    char  pBuf[iLen];
    char  pOldBuf[iLen];

    memset(pBuf,0,iLen);
    memset(pOldBuf,0,iLen);
    memcpy(pOldBuf,str.c_str(),str.length());
	int iRet = CTStringUtils::GbToUtf8(pOldBuf,str.length()+1,pBuf,iLen-1);
    std::string sRet;
    if(iRet>=0)
    {
        sRet=  pBuf;
    }

    return sRet;

}


